--yleaf(yaroot@gmail.com)
-- codes are taken from oChat, evl, etc.

local backdrop = {
	bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
	edgeFile = "", 
	tile = false, tileSize = 0, edgeSize = 0, 
	insets = {top = 0, left = 0, bottom = 0, right = 0},
}

local _AddMessage = ChatFrame1.AddMessage
local _SetItemRef = SetItemRef

local buttons = {'UpButton', 'DownButton', 'BottomButton'}
local dummy = function() end
--local ts = '|cffffffff|HyChat|h%s|h|||r %s'
--local ts = '|cffffffff|HyChat|h%s|h|r %s'
local ts = '|cff424242|HyChat|h%s|h|r %s'

_G.CHAT_GUILD_GET = '|Hchannel:Guild|hg|h %s:\32'
_G.CHAT_RAID_GET = '|Hchannel:raid|hr|h %s:\32'
_G.CHAT_PARTY_GET = '|Hchannel:Party|hp|h %s:\32'
_G.CHAT_RAID_WARNING_GET = 'rw %s:\32'
_G.CHAT_RAID_LEADER_GET = '|Hchannel:raid|hR|h %s:\32'
_G.CHAT_OFFICER_GET = '|Hchannel:o|ho|h %s:\32'
_G.CHAT_BATTLEGROUND_GET = '|Hchannel:Battleground|hb|h %s:\32'
_G.CHAT_BATTLEGROUND_LEADER_GET = '|Hchannel:Battleground|hB|h %s:\32'
_G.CHAT_WHISPER_GET = 'from %s:\32'
_G.CHAT_WHISPER_INFORM_GET = 'to %s:\32'

-- 1: index, 2: channelname, 3: twatt
-- Examples are based on this: [1. Channel] Otravi: Hi
--local str = '[%2$.3s] %s' -- gives: [Cha] Otravi: Hi
--local str = '[%d. %2$.3s] %s' -- gives: [1. Cha] Otravi: Hi
local str = '%d|h %3$s' -- gives: 1 Otravi: Hi
local channel = function(...)
	return str:format(...)
end

local AddMessage = function(self, text, ...)
	if(type(text) == 'string') then
		text = text:gsub('|Hplayer:([^:]+):(%d+)|h%[(.-)%]|h', '|Hplayer:%1:%2|h%3|h')
		text = text:gsub('%[(%d+)%. (.+)%].+(|Hplayer.+)', channel)

		--text = ts:format(date'%H:%M:%S', text)
		text = ts:format(date'*', text)
	end

	return _AddMessage(self, text, ...)
end

local scroll = function(self, dir)
	if(dir > 0) then
		if(IsShiftKeyDown()) then
			self:ScrollToTop()
		elseif(IsControlKeyDown())	then
			for i=1,3 do self:ScrollUp() end
		else
			self:ScrollUp()
		end
	elseif(dir < 0) then
		if(IsShiftKeyDown()) then
			self:ScrollToBottom()
		elseif(IsControlKeyDown())	then
			for i=1,3 do self:ScrollDown() end
		else
			self:ScrollDown()
		end
	end
end

for i=1, NUM_CHAT_WINDOWS do
	local cf = _G['ChatFrame'..i]
	cf:EnableMouseWheel(true)
	
	cf:SetFading(false)
	cf:SetScript('OnMouseWheel', scroll)
	
	--cf:SetFont(STANDARD_TEXT_FONT, 12, 'OUTLINE')
	--cf:SetShadowColor(0,0,0)
	--cf:SetShadowOffset(.1, -.1)	

	for k, button in pairs(buttons) do
		button = _G['ChatFrame'..i..button]
		button:Hide()
		button.Show = dummy
	end
	
	if(i ~= 2) then
		cf.AddMessage = AddMessage
		cf:SetMaxLines(1000)
	end
end

buttons = nil

ChatFrameMenuButton:Hide()
--ChatFrameMenuButton.Show = dummy
ChatFrameMenuButton:SetParent(ChatFrame1)
ChatFrameMenuButton:SetParent(UIParent)
ChatFrameMenuButton:SetAlpha(.5)
ChatFrameMenuButton:ClearAllPoints()
ChatFrameMenuButton:SetPoint('TOPRIGHT', ChatFrame1, 0, 0)

local eb = ChatFrameEditBox
eb:ClearAllPoints()
eb:SetPoint('BOTTOMLEFT', ChatFrame1, 'TOPLEFT', -5, 0)
eb:SetPoint('BOTTOMRIGHT', ChatFrame1, 'TOPRIGHT', -15, 0)
eb:SetAltArrowKeyMode(false)

do
	local a, b, c = select(6, eb:GetRegions())
	a:Hide()
	b:Hide()
	c:Hide()
end

ChatTypeInfo['SAY'].sticky = 1
ChatTypeInfo['YELL'].sticky = 0
ChatTypeInfo['EMOTE'].sticky = 0
ChatTypeInfo['PARTY'].sticky = 1
ChatTypeInfo['GUILD'].sticky = 1
ChatTypeInfo['OFFICER'].sticky = 0
ChatTypeInfo['RAID'].sticky = 1
ChatTypeInfo['RAID_WARNING'].sticky = 0
ChatTypeInfo['BATTLEGROUND'].sticky = 1
ChatTypeInfo['WHISPER'].sticky = 0
ChatTypeInfo['CHANNEL'].sticky = 1
--[[	check what you want
ChatTypeInfo['CHANNEL1'].sticky = 0
ChatTypeInfo['CHANNEL2'].sticky = 0
ChatTypeInfo['CHANNEL3'].sticky = 0
ChatTypeInfo['CHANNEL4'].sticky = 0
ChatTypeInfo['CHANNEL5'].sticky = 0
ChatTypeInfo['CHANNEL6'].sticky = 0
ChatTypeInfo['CHANNEL7'].sticky = 0
ChatTypeInfo['CHANNEL8'].sticky = 0
ChatTypeInfo['CHANNEL9'].sticky = 0
ChatTypeInfo['CHANNEL10'].sticky = 0
]]

-- Modified version of MouseIsOver from UIParent.lua
local MouseIsOver = function(frame)
	local s = frame:GetParent():GetEffectiveScale()
	local x, y = GetCursorPosition()
	x = x / s
	y = y / s

	local left = frame:GetLeft()
	local right = frame:GetRight()
	local top = frame:GetTop()
	local bottom = frame:GetBottom()

	-- Hack to fix a symptom not the real issue
	if(not left) then
		return
	end

	if((x > left and x < right) and (y > bottom and y < top)) then
		return 1
	else
		return
	end
end

local borderManipulation = function(...)
	for l = 1, select('#', ...) do
		local obj = select(l, ...)
		if(obj:GetObjectType() == 'FontString' and MouseIsOver(obj)) then
			return obj:GetText()
		end
	end
end

SetItemRef = function(link, text, button, ...)
	if(link:sub(1, 5) ~= 'yChat') then return _SetItemRef(link, text, button, ...) end

	local text = borderManipulation(SELECTED_CHAT_FRAME:GetRegions())
	if(text) then
		text = text:gsub('|c%x%x%x%x%x%x%x%x(.-)|r', '%1')
		text = text:gsub('|H.-|h(.-)|h', '%1')

		eb:Insert(text)
		eb:Show()
		eb:HighlightText()
		eb:SetFocus()
	end
end

local editbox = CreateFrame('Button', nil, ChatFrameEditBox)
editbox:SetBackdrop(backdrop)
editbox:SetPoint('TOPLEFT', 'ChatFrameEditBoxLeft', 'TOPLEFT', 4, -2)
editbox:SetPoint('BOTTOMRIGHT', 'ChatFrameEditBoxRight', 'BOTTOMRIGHT', 16, 3)
editbox:SetFrameLevel(ChatFrameEditBox:GetFrameLevel()-1)

local function colorize(r,g,b)
	if type(r) == 'table' then
		if r.r then
			r,g,b = r.r, r.g, r.b
		else
			r,g,b = unpack(r)
		end
	end
	if r and g and b then
		editbox:SetBackdropBorderColor(r,g,b)
		editbox:SetBackdropColor(r/5,g/5,b/5)
	end
end

hooksecurefunc('ChatEdit_UpdateHeader', function()
	local type = DEFAULT_CHAT_FRAME.editBox:GetAttribute('chatType')
	if ( type == 'CHANNEL' ) then
		local id = GetChannelName(DEFAULT_CHAT_FRAME.editBox:GetAttribute('channelTarget'))
		if id == 0 then	colorize(0.5,0.5,0.5)
		else colorize(ChatTypeInfo[type..id])
		end
	else colorize(ChatTypeInfo[type])
	end
end)

function ChatEdit_OnTabPressed(self)
	local chatType = self:GetAttribute('chatType')
	local inBG = UnitInBattleground('player') and true
	local inRaid = GetRealNumRaidMembers() > 0 and true
	local inParty = GetRealNumPartyMembers() > 0 and true
	local inGuild = IsInGuild() and true
	local setType
	if chatType == 'SAY' then
		setType = inBG and 'BATTLEGROUND' or inRaid and 'RAID' or inParty and 'PARTY' or inGuild and 'GUILD' or 'SAY'
	elseif chatType == 'BATTLEGROUND' then
		setType = inRaid and 'RAID' or inParty and 'PARTY' or inGuild and 'GUILD' or 'SAY'
	elseif chatType == 'RAID' then
		setType = inParty and 'PARTY' or inGuild and 'GUILD' or 'SAY'
	elseif chatType == 'PARTY' then
		setType = inGuild and 'GUILD' or 'SAY'
	elseif chatType == 'GUILD' then
		setType = 'OFFICER'
	elseif chatType == 'OFFICER' then
		setType = 'SAY'
	end
	
	if setType then
		self:SetAttribute('chatType', setType)
		ChatEdit_UpdateHeader(self)
	else
		ChatEdit_SecureTabPressed(self)
	end
end

local ChannelSounds = {
	[5] = 'Sound\\Interface\\VoiceChatOn.wav',
	[8] = 'Sound\\Interface\\VoiceChatOn.wav',
}

local ChatSound, pName = CreateFrame'Frame', UnitName'player'
local ChatSoundEvents = {
	--['CHAT_MSG_GUILD'] = 'Sound\\Interface\\VoiceChatOn.wav',
	--['CHAT_MSG_OFFICER'] = 'Sound\\Interface\\VoiceChatOn.wav',
	['CHAT_MSG_WHISPER'] = 'Sound\\Interface\\iTellMessage.wav',
	['CHAT_MSG_PARTY'] = 'Sound\\Interface\\PlaceHolder.wav',
	['CHAT_MSG_RAID'] = 'Sound\\Interface\\PlaceHolder.wav',
	['CHAT_MSG_RAID_LEADER'] = 'Sound\\Interface\\PlaceHolder.wav',
	['CHAT_MSG_BATTLEGROUND'] = 'Sound\\Interface\\PlaceHolder.wav',
	['CHAT_MSG_BATTLEGROUND_LEADER'] = 'Sound\\Interface\\PlaceHolder.wav',
--[[
	['CHAT_MSG_CHANNEL'] = function(msg, sender, _, _, _, _, _, ChannelNum, ...)
		return ChannelNum and (sender ~= pName) and ChannelSounds[ChannelNum]
	end,
]]
}

for k, v in pairs(ChatSoundEvents) do
	if k and v then
		ChatSound:RegisterEvent(k)
	end
end

ChatSound:SetScript('OnEvent', function(self, event, msg, sender, ...)
	if (not event) or (not msg) then return end
	if sender and sender==pName then return end
	
	-- check if the msg is filted
	local filter = ChatFrame_GetMessageEventFilters(event)
	if filter then
		for _, func in pairs(filter) do
			local filted, newmsg = func(self, event, msg, sender, ...)
			if filted and (not newmsg) then return end
		end
	end
	
	local sound = ChatSoundEvents[event]
	if sound and type(sound) == 'function' then
		sound = sound(msg, sender, ...)
	end
	if sound and type(sound) == 'string' then
		PlaySoundFile(sound)
	end
end)


local bg = CreateFrame('Frame', nil, UIParent)

bg:RegisterEvent'ADDON_LOADED'
bg:SetScript('OnEvent', function(self, event, addon)
	if(addon == 'Blizzard_GMChatUI') then
		GMChatFrame:EnableMouseWheel(true)
		GMChatFrame:SetFading(false)
		GMChatFrame:SetScript('OnMouseWheel', scroll)
		GMChatFrame:SetHeight(GMChatFrame:GetHeight() * 3)

		GMChatFrameUpButton:Hide()
		GMChatFrameUpButton.Show = dummy
		
		GMChatFrameDownButton:Hide()
		GMChatFrameDownButton.Show = dummy
		
		GMChatFrameBottomButton:Hide()
		GMChatFrameBottomButton.Show = dummy
		
		bg:UnregisterAllEvents()
		bg:SetScript('OnEvent', nil)
	end
end)
